﻿#region Namespaces

using System;
using System.Drawing;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Data;
using System.Windows.Forms;
using LumenWorks.Framework.IO.Csv;
using SdmxMl.Structure;
using SdmxMl.Manager;
using SdmxMl.Data;
using SdmxMl.Common;

#endregion

namespace SdmxMl.Panels
{
    /// <summary> CSV data viewer-checker modeless dialog </summary>
    public partial class DlgDataCsv : Form
    {
        #region Internal Members

        private RefVarHelper refVarHelper;
        private CsvDataHeader metaDataHeader;
        private KeyFamilyType dsd;
        private CsvProperties CsvConfig;
        private CsvChuncher chunker;
        private List<string> headerFields;
        private int currentChunk;
        private string currentCsvpath;

        #endregion

        #region Constructor

        public DlgDataCsv(CsvProperties cp)
        {
            CsvConfig = cp;
            InitializeComponent();
            groupBoxNavigation.Enabled = false;
            currentChunk = 0;
            ShowCounts(0, 0, 0);
            currentCsvpath = string.Empty;
            loadPreviousDiagnosticToolStripMenuItem.Enabled = false;
            eSurveyToolStripMenuItem.Enabled = false;
        }
        #endregion

        #region Count infos

        private void ShowCounts(int col, int row, int matches)
        {
            textBoxColCount.Text = col.ToString();
            textBoxMatches.Text = matches.ToString();
            textBoxRowCount.Text = row.ToString();

            if (chunker != null && chunker.ChunkList != null && chunker.ChunkList.Count > 0)
            {
                textBoxChunkYesNo.Text = "YES";
                textBoxChunkCount.Text = chunker.ChunkList.Count.ToString();
            }
            else
            {
                textBoxChunkYesNo.Text = chunker == null ? string.Empty : "NO";
                textBoxChunkCount.Text = "0";
            }

        }
        #endregion

        #region Reading CSV file

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            eSurveyToolStripMenuItem.Enabled = false;
            textBoxInfo.Text = string.Empty;
            chunker = new CsvChuncher(CsvConfig);
            try
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    loadPreviousDiagnosticToolStripMenuItem.Enabled = false;

                    string csvBloc = openFileDialog.FileName;
                    currentCsvpath = openFileDialog.FileName;
                    currentChunk = 0;
                    ShowCounts(0, 0, 0);
                    if (chunker.IsChunckCandidate(currentCsvpath))
                    {
                        DlgHugeFile adlg = new DlgHugeFile(chunker.GetChunkInfoList(currentCsvpath) == true);
                        DialogResult result = adlg.ShowDialog(this);
                        if (result == DialogResult.Cancel)
                        {
                            currentCsvpath = string.Empty;
                            return;
                        }
                        if (result == DialogResult.Retry)
                        {
                            vScrollBarChunk.Visible = true;
                            textBoxCurrrentChunk.Visible = true;
                            labelChunk.Visible = true;
                            chunker.GetChunkInfoList(currentCsvpath);
                            currentChunk = 1;
                            csvBloc = chunker.GetChunkPath(currentCsvpath, currentChunk);
                            vScrollBarChunk.Maximum = chunker.ChunkList.Count + 20;
                            textBoxCurrrentChunk.Text = currentChunk.ToString();
                            currentChunkToolStripMenuItem.Enabled = true;

                        }
                        else
                        {
                            StringBuilder sb = new StringBuilder();
                            DateTime startTime = DateTime.Now;
                            using (new SdmxMl.Helper.CWaitCursor())
                            {
                                vScrollBarChunk.Visible = true;
                                textBoxCurrrentChunk.Visible = true;
                                labelChunk.Visible = true;

                                chunker.CreateChunks(openFileDialog.FileName);
                                currentChunk = 1;
                                csvBloc = chunker.GetChunkPath(currentCsvpath, currentChunk);
                                vScrollBarChunk.Maximum = chunker.ChunkList.Count + 20;
                                textBoxCurrrentChunk.Text = currentChunk.ToString();
                                currentChunkToolStripMenuItem.Enabled = true;


                                DateTime stopTime = DateTime.Now;
                                TimeSpan duration = stopTime - startTime;
                                sb.Append("hours:").Append(duration.Hours).Append(Environment.NewLine);
                                sb.Append("minutes:").Append(duration.Minutes).Append(Environment.NewLine);
                                sb.Append("seconds:").Append(duration.Seconds).Append(Environment.NewLine);
                                sb.Append("milliseconds:").Append(duration.Milliseconds).Append(Environment.NewLine);
                            }

                            MessageBox.Show(sb.ToString());

                        }
                    }
                    else
                    {
                        currentChunkToolStripMenuItem.Enabled = false;
                        vScrollBarChunk.Visible = false;
                        textBoxCurrrentChunk.Visible = false;
                        labelChunk.Visible = false;

                    }


                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvBloc, Encoding.Default), true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                        {

                            this.dataGrid.Columns.Clear();
                            DataGridViewColumn[] columns = new DataGridViewColumn[csv.FieldCount];
                            headerFields = new List<string>(csv.GetFieldHeaders());
                            for (int i = 0; i < columns.Length; ++i) 
                            {
                                headerFields[i] = headerFields[i].ToUpper();
                                DataGridViewColumn column = new DataGridViewTextBoxColumn(); 
                                column.FillWeight = 1;
                                column.HeaderText = headerFields[i];
                                column.DataPropertyName = column.Name = column.HeaderText;
                                columns[i] = column; 
                            } 
                            this.dataGrid.Columns.AddRange(columns);
                            dataGrid.AutoGenerateColumns = false;
                            dataGrid.EnableHeadersVisualStyles = false;
                            dataGrid.DataSource = csv;

                            textBoxInfo.Text = "File: " + openFileDialog.FileName + " loaded.";


                            //dataGrid.Rows[2].Cells[4].Style.BackColor = Color.OrangeRed;

                            // Hide error grid
                            splitContainer.Panel1Collapsed = true;

                            // Reset Header info
                            metaDataHeader = null;
                            ShowCounts(dataGrid.ColumnCount, dataGrid.RowCount, 0);

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        #endregion

        #region Get Header Meta

        private void headerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            textBoxInfo.Text = string.Empty;
            dsd = null;
            eSurveyToolStripMenuItem.Enabled = false;

            if (dataGrid.DataSource == null)
            {
                MessageBox.Show(this, "Csv file is not loaded!", "Checking error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
           }

            try
            {
                dsd = GetSelectedDsd();

                if (dsd != null)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        // Refresh image of matadata
                        refVarHelper = new RefVarHelper(ReferenceManager.GetSmContainerImage());

                        // Record Header info
                        metaDataHeader = new CsvDataHeader(dsd, headerFields, refVarHelper);
                        ShowCounts(dataGrid.ColumnCount, dataGrid.RowCount, metaDataHeader.DicoHeadCol.Count);
                        textBoxModel.Text = metaDataHeader.Model == CsvModel.ColumnModel ? "Columns" : "Linear";
                        ColorizeColumns();
                        loadPreviousDiagnosticToolStripMenuItem.Enabled = true;
                        if (metaDataHeader.ListDsdColNotInCsv.Count > 0)
                        {
                            StringBuilder sb = new StringBuilder();
                            foreach (string s in metaDataHeader.ListDsdColNotInCsv)
                                sb.Append(s).Append("  ");
                            MessageBox.Show(this, "Caution Some DSD items are not present in CSV file:" + Environment.NewLine + sb.ToString(),
                                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                    }

                    splitContainer.Panel1Collapsed = metaDataHeader.DicoHeadCol.Count > 0;
                }
                else
                {
                    MessageBox.Show(this, "No DSD selected in main tree!", "Checking error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                if (metaDataHeader == null)
                {
                    textBoxInfo.Text = "No associated metadata found!";
                }
                else if (metaDataHeader.DicoHeadCol.Count != dataGrid.Columns.Count)
                {
                    textBoxInfo.Text = string.Format("Caution: {0} CSV columns are not described by DSD!", dataGrid.Columns.Count - metaDataHeader.DicoHeadCol.Count);
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
           
            groupBoxNavigation.Enabled = metaDataHeader != null;

        }

        private void ColorizeColumns()
        {
            if (dataGrid.DataSource != null && metaDataHeader != null)
            {
                for (int columnIndex = 0; columnIndex < dataGrid.Columns.Count; ++columnIndex)
                {
                    if (metaDataHeader.DicoHeadCol.ContainsKey(columnIndex))
                    {
                        CsvMetaHeaderCol metaCol = metaDataHeader.DicoHeadCol[columnIndex];
                        if (metaCol.BaseVar is DimensionType || metaCol.BaseVar is TimeDimensionType)
                            dataGrid.Columns[columnIndex].HeaderCell.Style.BackColor = panelKey.BackColor;
                        else if (metaCol.BaseVar is AttributeType)
                            dataGrid.Columns[columnIndex].HeaderCell.Style.BackColor = panelAttrib.BackColor;
                        else if (metaCol.BaseVar is CrossSectionalMeasureType || metaCol.BaseVar is PrimaryMeasureType)
                            dataGrid.Columns[columnIndex].HeaderCell.Style.BackColor = panelMeasure.BackColor; 

                    }
                }


            }
        }

        private KeyFamilyType GetSelectedDsd()
        {
            KeyFamilyType dsdSelected = null;
            if (ReferenceManager.TreeSdmx.SelectedNode != null)
            {
                dsdSelected = ReferenceManager.TreeSdmx.SelectedNode.Tag as KeyFamilyType;
            }

            return dsdSelected;
        }
        #endregion

        #region Datagrid Events

        /// <summary>
        /// this method overrides the DataGridView's RowPostPaint event in order to automatically
        /// draw numbers on the row header cells and to automatically adjust the width of the
        /// column containing the row header cells so that it can accommodate the new row
        /// numbers.
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void Grid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            DataGridView grdActiveSheet = sender as DataGridView;

            if (grdActiveSheet != null)
            {
                //store a string representation of the row number in 'strRowNumber'
                 int rowNum = e.RowIndex + 1;
                 if (chunker != null && chunker.ChunkList != null && currentChunk >= 1)
                     rowNum = chunker.ChunkList[currentChunk-1].RowStart + e.RowIndex;

                 string strRowNumber = String.Format("{0:000000}", rowNum); 

                //determine the display size of the row number string using
                //the DataGridView's current font.
                SizeF size = e.Graphics.MeasureString(strRowNumber, this.Font);

                //adjust the width of the column that contains the row header cells 
                //if necessary
                if (grdActiveSheet.RowHeadersWidth < (int)(size.Width + 20)) grdActiveSheet.RowHeadersWidth = (int)(size.Width + 20);

                //this brush will be used to draw the row number string on the
                //row header cell using the system's current ControlText color
                Brush b = SystemBrushes.ControlText;

                //draw the row number string on the current row header cell using
                //the brush defined above and the DataGridView's default font
                e.Graphics.DrawString(strRowNumber, this.Font, b, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + ((e.RowBounds.Height - size.Height) / 2));

                //call the base object's OnRowPostPaint method

                //   grdActiveSheet.OnRowPostPaint(e);
            }
        }

        /// <summary> Disable column sorting</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void dataGrid_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
        {
            e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
        }

        /// <summary> Tooltip on data cell or concept header </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void dataGrid_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e)
        {
            if (sender is DataGridView)
            {
                if (metaDataHeader != null)
                {
                    if (metaDataHeader.DicoHeadCol.ContainsKey(e.ColumnIndex))
                    {
                        CsvMetaHeaderCol metaCol = metaDataHeader.DicoHeadCol[e.ColumnIndex];

                        // If header column
                        if (e.RowIndex < 0)
                        {
                            e.ToolTipText = metaCol.Concept.Name.ToString();
                        }
                        else
                        {
                            if (metaCol.Codelist != null)
                            {
                                CodeType c = metaCol.Codelist.CodeList.LocateItem(dataGrid[e.ColumnIndex, e.RowIndex].Value.ToString()) as CodeType;
                                if (c != null)
                                    e.ToolTipText = c.Name.ToString();
                            }
                            if (string.IsNullOrEmpty(e.ToolTipText))
                            {
                                if (metaCol.CodeQuality != null)
                                {
                                    CodeType c = metaCol.CodeQuality.CodeList.LocateItem(dataGrid[e.ColumnIndex, e.RowIndex].Value.ToString()) as CodeType;
                                    if (c != null)
                                        e.ToolTipText = c.Name.ToString();
                                }
                            }
                        }
                   }
                }
            }
        }
        #endregion

        #region Navigation Events

        private void buttonNavigateConcept_Click(object sender, EventArgs e)
        {
            if (metaDataHeader != null && dataGrid.SelectedCells != null && dataGrid.SelectedCells.Count > 0)
            {
                int columnIndex = dataGrid.SelectedCells[0].ColumnIndex;
                if (metaDataHeader.DicoHeadCol.ContainsKey(columnIndex))
                {
                    CsvMetaHeaderCol metaCol = metaDataHeader.DicoHeadCol[columnIndex];

                    string urn = UrnManager.FullIdToUrn(SdmxArtefactType.Concepts.ToString(),
                        metaCol.ConceptScheme.FullIdent, metaCol.Concept, null);
                    UrnParser p = new UrnParser(urn);

                    // If already in memory, navigate otherwhile get from regidtry
                    if (NavigationManager.LocatenavigateProject(SdmxArtefactType.Concepts, metaCol.ConceptScheme.FullIdent, p) == null)
                        NavigationManager.NavigateWithRegistry(SdmxArtefactType.Concepts, metaCol.ConceptScheme.FullIdent, true, p);
                }
            }
        }

        private void buttonNavigateCodelist_Click(object sender, EventArgs e)
        {
            if (metaDataHeader != null && dataGrid.SelectedCells != null && dataGrid.SelectedCells.Count > 0)
            {
                int columnIndex = dataGrid.SelectedCells[0].ColumnIndex;
                if (metaDataHeader.DicoHeadCol.ContainsKey(columnIndex))
                {
                    try
                    {
                        CsvMetaHeaderCol metaCol = metaDataHeader.DicoHeadCol[columnIndex];
                        if (metaCol.Codelist != null)
                        {
                            // If already in memory, navigate otherwhile get from registry
                            if (NavigationManager.LocatenavigateProject(SdmxArtefactType.CodeLists, metaCol.Codelist.FullIdent, null) == null)
                                NavigationManager.NavigateWithRegistry(SdmxArtefactType.CodeLists, metaCol.Codelist.FullIdent, true, null);

                            if (ReferenceManager.TreeSdmx.SelectedNode != null &&
                                ReferenceManager.TreeSdmx.SelectedNode.Tag is CodeListType)
                                ReferenceManager.TreeSdmx.SelectedNode.ExpandAll();
                        }
                    }

                    catch (Exception ex)
                    {
                        MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                }
            }
        }

        private void buttonNavigateDsd_Click(object sender, EventArgs e)
        {
            if (dsd != null && metaDataHeader != null && dataGrid.SelectedCells != null && dataGrid.SelectedCells.Count > 0)
            {
                int columnIndex = dataGrid.SelectedCells[0].ColumnIndex;
                if (columnIndex >= 0 && metaDataHeader.DicoHeadCol.ContainsKey(columnIndex))
                {
                    try
                    {
                        CsvMetaHeaderCol metaCol = metaDataHeader.DicoHeadCol[columnIndex];
                        string urn = UrnManager.FullIdToUrn(SdmxArtefactType.KeyFamilies.ToString(), dsd.FullIdent, metaCol.BaseVar, null);
                        UrnParser p = new UrnParser(urn);

                        // If already in memory, navigate otherwhile get from regidtry
                        if (NavigationManager.LocatenavigateProject(SdmxArtefactType.KeyFamilies, dsd.FullIdent, p) == null)
                            NavigationManager.NavigateWithRegistry(SdmxArtefactType.KeyFamilies, dsd.FullIdent, true, p);
                    }

                    catch (Exception ex)
                    {
                        MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
        #endregion

        #region Error Grid Events

        /// <summary>User request to show data cell matching error </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void dataGridError_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.RowIndex >= 0)
                {
                    DataTable tb = dataGridError.DataSource as DataTable;
                    if (tb != null)
                    {
                        int chunk = Convert.ToInt32(tb.Rows[e.RowIndex][2].ToString());
                        int row = Convert.ToInt32(tb.Rows[e.RowIndex][3].ToString());
                        int col = Convert.ToInt32(tb.Rows[e.RowIndex][4].ToString().ToString());

                        if (chunk > 0 && chunk != currentChunk)
                        {
                            currentChunk = chunk;
                            vScrollBarChunk.Value = currentChunk - 1;
                        }
                        if (chunk > 0)
                            row -= chunker.ChunkList[currentChunk - 1].RowStart;
                        else
                            row -= 1;

                        dataGrid[col, row].Selected = true;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void buttonExcelErrReport_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridError.DataSource != null)
                {
                    DataTable tb = dataGridError.DataSource as DataTable;
                    if (saveFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName, false, Encoding.UTF8))
                        {
                            sw.Close();
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region Csv Option Menu event

        private void cSVFormatToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                DlgCsvProperties aDlg = new DlgCsvProperties(CsvConfig);
                aDlg.ShowDialog(this);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region Chunk Bar Events

        private void vScrollBarChunk_ValueChanged(object sender, EventArgs e)
        {
            if (chunker != null && chunker.ChunkList != null && chunker.ChunkList.Count > 0)
            {
                int index = (sender as VScrollBar).Value;
                index = Math.Max(0, index);
                index = Math.Min(chunker.ChunkList.Count-1, index);
                currentChunk = index + 1;
                textBoxCurrrentChunk.Text = currentChunk.ToString();
                using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(
                    chunker.GetChunkPath(currentCsvpath, currentChunk), Encoding.Default),
                    true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                {
                    dataGrid.DataSource = csv;
                    ShowCounts(dataGrid.ColumnCount, dataGrid.RowCount, 0);

                }
            }
        }
        #endregion

        #region Validation Menu Events

        private void fullToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Pre conditions
            if (metaDataHeader == null)
            {
                MessageBox.Show("Please bind metadata first!", "Checking", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            try
            {

                CsvMetaCheck checker = new CsvMetaCheck(metaDataHeader);
                checker.MaxErrPerCol = Convert.ToInt32(numTextBoxMaxPerCol.Text);
                checker.MaxErrTotal = Convert.ToInt32(numTextBoxMaxTotal.Text);
                DateTime startTime = DateTime.Now;
                if (chunker == null || chunker.ChunkList == null || chunker.ChunkList.Count == 0)
                {
                    CsvChunk chunk = new CsvChunk(0, 1);
                    using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(
                       currentCsvpath, Encoding.Default),
                       true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                    {
                        checker.CheckChunk(csv, chunk);
                    }
                    checker.PersistErrorTable(currentCsvpath);

               }
                else
                {
                    foreach (CsvChunk chunk in chunker.ChunkList)
                    {
                        textBoxInfo.Text = "Checking chunk: " + chunk.ChunkId.ToString();
                        textBoxInfo.Refresh();

                        using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(
                            chunker.GetChunkPath(currentCsvpath, chunk.ChunkId), Encoding.Default),
                            true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                        {
                            checker.CheckChunk(csv, chunk);

                            if (checker.ErrorCount >= checker.MaxErrTotal)
                                break;
                        }
                    }
                    checker.PersistErrorTable(currentCsvpath);   
                }


                DateTime stopTime = DateTime.Now;
                TimeSpan duration = stopTime - startTime;
                StringBuilder sb = new StringBuilder();
                sb.Append("hours:").Append(duration.Hours).Append(Environment.NewLine);
                sb.Append("minutes:").Append(duration.Minutes).Append(Environment.NewLine);
                sb.Append("seconds:").Append(duration.Seconds).Append(Environment.NewLine);
                sb.Append("milliseconds:").Append(duration.Milliseconds).Append(Environment.NewLine);

                if (checker.ErrorCount >= checker.MaxErrTotal) 
                    textBoxInfo.Text = "too many errors, stopped!";
                else
                    textBoxInfo.Text = "Detected errors: " + checker.ErrorCount.ToString();

                MessageBox.Show(sb.ToString());

                if (checker.ErrorCount > 0)
                {
                    dataGridError.AutoGenerateColumns = false;
                    dataGridError.DataSource = checker.ErrorTable;

                }
                else
                {
                    MessageBox.Show("NO error detected.", "Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    eSurveyToolStripMenuItem.Enabled = true;
                }

 
                // Show or hide error grid
                splitContainer.Panel1Collapsed = checker.ErrorCount == 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        

        private void currentChunkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Pre conditions
            if (metaDataHeader == null)
            {
                MessageBox.Show("Please bind metadata first!", "Checking", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            try
            {
                CsvChunk chunk = chunker.ChunkList[currentChunk-1];
                CsvMetaCheck checker = new CsvMetaCheck(metaDataHeader);
                checker.MaxErrPerCol = Convert.ToInt32(numTextBoxMaxPerCol.Text);
                checker.MaxErrTotal = Convert.ToInt32(numTextBoxMaxTotal.Text);
                DateTime startTime = DateTime.Now;
                        textBoxInfo.Text = "Checking chunk: " + chunk.ChunkId.ToString();
                        textBoxInfo.Refresh();

                using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(
                    chunker.GetChunkPath(currentCsvpath, chunk.ChunkId), Encoding.Default),
                    true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                {
                    checker.CheckChunk(csv, chunk);
                }

                DateTime stopTime = DateTime.Now;
                TimeSpan duration = stopTime - startTime;
                StringBuilder sb = new StringBuilder();
                sb.Append("hours:").Append(duration.Hours).Append(Environment.NewLine);
                sb.Append("minutes:").Append(duration.Minutes).Append(Environment.NewLine);
                sb.Append("seconds:").Append(duration.Seconds).Append(Environment.NewLine);
                sb.Append("milliseconds:").Append(duration.Milliseconds).Append(Environment.NewLine);

                if (checker.ErrorCount >= checker.MaxErrTotal)
                    textBoxInfo.Text = "too many errors, stopped!";
                else
                    textBoxInfo.Text = "Detected errors: " + checker.ErrorCount.ToString();

                MessageBox.Show(sb.ToString());

                if (checker.ErrorCount > 0)
                {
                    dataGridError.AutoGenerateColumns = false;
                    dataGridError.DataSource = checker.ErrorTable;

                }
                else
                    MessageBox.Show("NO error detected.", "Check", MessageBoxButtons.OK, MessageBoxIcon.Information);

                // Show or hide error grid
                splitContainer.Panel1Collapsed = checker.ErrorCount == 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
        #endregion

        private void buttonLoadDiagnostic_Click(object sender, EventArgs e)
        {

        }

        private void loadPreviousDiagnosticToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (metaDataHeader != null && currentCsvpath != null && currentCsvpath.Length > 0)
                {
                    if (File.Exists(CsvChuncher.GetChunkInfoErrorPath(currentCsvpath)))
                    {
                        DataSet ds = new DataSet();
                        ds.ReadXml(CsvChuncher.GetChunkInfoErrorPath(currentCsvpath));
                        if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                        {
                            dataGridError.AutoGenerateColumns = false;
                            dataGridError.DataSource = ds.Tables[0];
                            splitContainer.Panel1Collapsed = false;
                        }

                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }

        private void eSurveyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    EsurveyDataImport esDataImport = new EsurveyDataImport(this.metaDataHeader, this.dsd);

                    using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(
                      currentCsvpath, Encoding.Default),
                      true, CsvConfig.Delimiter, CsvConfig.Quote, CsvReader.DefaultEscape, CsvReader.DefaultComment, false))
                    {
                        esDataImport.produceExport(csv, saveFileDialog.FileName);
                    }
                    
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }
    }
}
